package com.koron.css2.workflow;

import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.koron.css2.ApplicationConfig;
import com.koron.css2.common.bean.MessageEntity;
import com.koron.css2.common.utils.HttpUtils;
import com.koron.css2.serviceManage.bean.ProcessNodeBean;
import com.koron.css2.serviceManage.utils.JsonUtils;
import com.koron.css2.workflow.bean.*;
import com.koron.util.Constant;
import com.koron.util.encode.RSAEncrypt;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.swan.bean.MessageBean;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 流程平台相关接口
 * @author admin
 *
 */
public class WorkflowImpl {

	private static Logger log = LogManager.getLogger(WorkflowImpl.class);

	/**
	 * 工程暂停
	 * @param setCode
	 * @param processCode
	 * @param processInstanceId
	 * @return
	 * @throws Exception
	 */
	public static MessageBean<?> suspend(String setCode, String processCode,String processInstanceId)  {
		String url = ApplicationConfig.workflowUrl + "/process/suspend.htm";
		Map<String, String> params = new HashMap<String, String>();
		params.put("secret", getSecret());
		params.put("setCode", setCode);
		params.put("processCode", processCode);
		params.put("processInstanceId", processInstanceId);
		try {
			String data = HttpUtils.sendPostJson(url,  JsonUtils.objectToJson(params));
			MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				throw new RuntimeException("获取流程节点信息失败：" + message.getDescription());
			}
			return message;
		}catch(Exception ex) {
			log.error("获取流程节点信息失败：" + ex.getMessage());
			throw new RuntimeException("获取流程节点信息失败：" + ex.getMessage());
		}
	}
	/**
	 * 工程恢复
	 * @param setCode
	 * @param processCode
	 * @param processInstanceId
	 * @return
	 * @throws Exception
	 */
	public static MessageBean<?> recovery(String setCode, String processCode,String processInstanceId) {
		String url = ApplicationConfig.workflowUrl + "/process/recovery.htm";
		Map<String, String> params = new HashMap<String, String>();
		params.put("secret", getSecret());
		params.put("setCode", setCode);
		params.put("processCode", processCode);
		params.put("processInstanceId", processInstanceId);
		try {
			String data = HttpUtils.sendPostJson(url,  JsonUtils.objectToJson(params));
			MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				throw new RuntimeException("获取流程节点信息失败：" + message.getDescription());
			}
			return message;
		}catch(Exception ex) {
			log.error("获取流程节点信息失败：" + ex.getMessage());
			throw new RuntimeException("获取流程节点信息失败：" + ex.getMessage());
		}

	}
	public static List<ProcessNodeBean> getWorkflowDefine(String setCode, String processCode) throws Exception {
		String url = ApplicationConfig.workflowUrl + "/process/define.htm";
		Map<String, String> params = new HashMap<String, String>();
		params.put("secret", getSecret());
		params.put("setCode", setCode);
		params.put("processCode", processCode);
		try {
			String data = HttpUtils.sendGetForm(url, params);
			MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				throw new RuntimeException("获取流程节点信息失败：" + message.getDescription());
			}
			return JsonUtils.objectToList(message.getData(), ProcessNodeBean.class);
		}catch(Exception ex) {
			log.error("获取流程节点信息失败：" + ex.getMessage());
			throw new RuntimeException("获取流程节点信息失败：" + ex.getMessage());
		}

	}

	public static NextTaskNodeInfoBean startProcessInstance(ProcessStartBean bean) {
		try {
			if(bean == null) {
				throw new RuntimeException("流程启动参数不能为空");
			}
			bean.setSecret(getSecret());
			if(bean.getFormVariables() != null) {
				bean.getFormVariables().put("urgent", 0);
			}
			String url = ApplicationConfig.workflowUrl + "/process/start.htm";
			String data = HttpUtils.sendPostJson(url, JsonUtils.objectToJson(bean));
			MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				throw new RuntimeException("流程启动失败：" + message.getDescription());
			}
			return JsonUtils.objectToPojo(message.getData(), NextTaskNodeInfoBean.class);
		}catch(Exception ex) {
			log.error("流程启动出错：" + ex.getMessage());
			throw new RuntimeException("流程启动出错：" + ex.getMessage());
		}
	}

	public static NextTaskNodeInfoBean workflowsubmit(ProcessCommitBean bean) {
		String url = ApplicationConfig.workflowUrl + "/process/submit.htm";
		try {
			bean.setSecret(getSecret());
			String data = HttpUtils.sendPostJson(url, JsonUtils.objectToJson(bean));
			MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				log.error("流程提交出错：" + message.getDescription());
				throw new RuntimeException("流程提交失败：" + message.getDescription());
			}
			return JsonUtils.objectToPojo(message.getData(), NextTaskNodeInfoBean.class);
		}catch(Exception ex) {
			log.error("流程提交出错：" + ex.getMessage());
			throw new RuntimeException("流程提交出错：" + ex.getMessage());
		}
	}

	public static List<HistoryTaskMsgBean> workflowhistory(String setCode, String processCode, String billId) {
		String url = ApplicationConfig.workflowUrl + "/process/history.htm";
		Map<String, String> params = new HashMap<String, String>();
		params.put("secret", getSecret());
		params.put("setCode", setCode);
		params.put("processCode", processCode);
		params.put("billId", billId);
		try {
			String data = HttpUtils.sendGetForm(url, params);
			MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				throw new RuntimeException("查询审批历史记录失败：" + message.getDescription());
			}
			log.info("" + message.getData());
			return JsonUtils.objectToList(message.getData(), HistoryTaskMsgBean.class);
		} catch(Exception ex) {
			throw new RuntimeException("查询审批历史记录失败：" + ex.getMessage());
		}
	}

	public static PageInfo<ProcessListBean> workflow(ProcessListQueryBean bean) {
		try {
			if(bean == null) {
				throw new RuntimeException("查询工作流列表参数不能为空");
			}
			String url = ApplicationConfig.workflowUrl + "/process/list.htm";
			Map<String, String> param = new HashMap<String, String>();
			param.put("secret", getSecret());
			if(StringUtils.isNotBlank(bean.getBillId())) {
				param.put("billId", bean.getBillId());
			}
			if(StringUtils.isNotBlank(bean.getEndDate())) {
				param.put("endDate", bean.getEndDate());
			}
			if(StringUtils.isNotBlank(bean.getOperator())) {
				param.put("operator", bean.getOperator());
			}
			if(StringUtils.isNotBlank(bean.getProcessCode())) {
				param.put("processCode", bean.getProcessCode());
			}
			if(StringUtils.isNotBlank(bean.getSetCode())) {
				param.put("setCode", bean.getSetCode());
			}
			if(StringUtils.isNotBlank(bean.getStartDate())) {
				param.put("startDate", bean.getStartDate());
			}
			if(StringUtils.isNotBlank(bean.getTitle())) {
				param.put("title", URLEncoder.encode(bean.getTitle(), "utf-8"));
			}
			if(bean.getStatus() != null) {
				param.put("status", bean.getStatus() + "");
			}
			if(bean.getType()!= null) {
				param.put("type", bean.getType() + "");
			}
			if(StringUtils.isNotBlank(bean.getCategory())) {
				param.put("category", bean.getCategory());
			}
			param.put("page", bean.getPage() + "");
			param.put("pageCount", bean.getPageCount() + "");
			String data = HttpUtils.sendGetForm(url, param);
			MessageEntity<?> message = JsonUtils.jsonToPojo(data, MessageEntity.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				throw new RuntimeException("查询工作流列表失败：" + message.getDescription());
			}
			List<ProcessListBean> result = JsonUtils.objectToList(message.getData(), ProcessListBean.class);
			PageInfo<ProcessListBean> page = new PageInfo<ProcessListBean>();
			page.setPageNum(bean.getPage());
			page.setPages(message.getTotalCount().intValue());
			page.setPageSize(bean.getPageCount());
			page.setTotal(message.getTotalCount());
			page.setList(result);
			return page;
		}catch(Exception ex) {
			throw new RuntimeException("查询工作流列表失败:" + ex.getMessage());
		}
	}

	public static String workflowShowView(String setCode, String processCode, String staffCode, String taskId, String processInstanceId, String billId) {
		try {
			String url = ApplicationConfig.workflowUrl + "/process/view.htm";
			Map<String, String> params = new HashMap<>();
			params.put("secret", getSecret());
			params.put("setCode", setCode);
			params.put("processCode", processCode);
			if(StringUtils.isNotEmpty(processInstanceId)) {
				params.put("processInstanceId", processInstanceId);
			}
			if(StringUtils.isNotEmpty(taskId)) {
				params.put("taskId", taskId);
			}
			if(StringUtils.isNotEmpty(billId)) {
				params.put("billId", billId);
			}
			params.put("operator", staffCode);
			String data = HttpUtils.sendGetForm(url, params);
			return data;
		}catch(Exception ex) {
			throw new RuntimeException("获取表单页面失败:" + ex.getMessage());
		}
	}

	/**
	 * 获取当前节点的下一个节点的信息
	 * @param variable 条件变量
	 * @param processInstanceId 流程实例ID
	 * @return
	 */
	public static Map<String, String> getNextTaskInfo(Map<String, Object> variable, String processInstanceId) {
		try {
			String url = ApplicationConfig.workflowUrl + "/process/getNextTaskInfo.htm";
			Map<String, String> params = new HashMap<>();
			params.put("secret", getSecret());
			params.put("variable", new Gson().toJson(variable));
			params.put("processInstanceId", processInstanceId);
			String result = HttpUtils.sendPostForm(url, params);
			MessageBean<?> message = JsonUtils.jsonToPojo(result, MessageBean.class);
			if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				throw new RuntimeException("查询下一个节点的信息失败：" + message.getDescription());
			}
			return JsonUtils.objectToPojo(message.getData(), Map.class);
		}catch(Exception ex) {
			throw new RuntimeException("查询下一个节点的信息失败:" + ex.getMessage());
		}
	}

	/**
	 * 查询工作流节点审批意见配置信息
	 * @return
	 */
	public static List<ApprovalCommentConfigBean> listApprovalCommentConfig(String setCode, String processCode, String taskCode) {
		try {
			String url = ApplicationConfig.workflowUrl + "/approvalCommentConfig/listByTaskCode";
			Map<String, String> params = new HashMap<>();
			params.put("setCode", setCode);
			params.put("processCode", processCode);
			params.put("taskCode", taskCode);
			params.put("type", "1");
			String data = HttpUtils.sendGetForm(url, params);
			MessageBean message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if (message.getCode() != Constant.MESSAGE_INT_SUCCESS){
				throw new RuntimeException(message.getDescription());
			}
			return JsonUtils.objectToList(message.getData(), ApprovalCommentConfigBean.class);
		}catch(Exception ex) {
			throw new RuntimeException("工作流节点审批意见配置信息查询失败:" + ex.getMessage());
		}
	}

	/**
	 * 添加工作流节点审批意见配置
	 * @param bean
	 * @return
	 */
	public static MessageBean<?> insertApprovalCommentConfig(ApprovalCommentConfigBean bean) {
		try {
			String url = ApplicationConfig.workflowUrl + "/approvalCommentConfig/insert";
			Map<String, String> params = new HashMap<>();
			params.put("setCode", bean.getSetCode());
			params.put("processCode", bean.getProcessCode());
			params.put("taskCode", bean.getTaskCode());
			params.put("createUser", bean.getCreateUser());
			params.put("comment", bean.getComment());
			params.put("type", "1");
			String data = HttpUtils.sendPostForm(url, params);
			MessageBean message = JsonUtils.jsonToPojo(data, MessageBean.class);
			if (message.getCode() != Constant.MESSAGE_INT_SUCCESS){
				throw new RuntimeException(message.getDescription());
			}
			return message;
		}catch(Exception ex) {
			throw new RuntimeException("工添加作流节点审批意见配置信息添加失败:" + ex.getMessage());
		}
	}

	/**
	 * 该接口是用于查询tblflow_node_attribute 这张表中的数据
	 *
	 * @param attributeValue  工作流表tblflow_node_attribute 中的 attribute_value 字段
	 * @param setCode 水司编号
	 * @param processCode 项目编号：css2之类的
	 * @param code 工作流的编号: pj_info_new 之类的
	 *
	 * @return tblflow_node_attribute中对应的信息
	 */
	public static MessageBean<?> getNodeInfo(String attributeValue, String setCode, String processCode, String code) {
		String url = ApplicationConfig.workflowUrl + "/process/getNodeInfo";
		Map<String, String> params = new HashMap<>();
		params.put("secret", getSecret());
		params.put("attributeValue", attributeValue);
		params.put("setCode", setCode);
		params.put("processCode", processCode);
		params.put("code", code);
		String data = HttpUtils.sendGetForm(url, params);
		MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
		if (message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
			MessageBean fail = MessageBean.create(Constant.MESSAGE_INT_FAIL,"节点信息获取失败，原因是： ", String.class);
			fail.setDescription(message.getDescription());
			return fail;
		}
		return message;
	}

	public static OverdueHistoryBean getOverdueInfo(String setCode, String processCode, String processInstanceId) {
		String url = ApplicationConfig.workflowUrl + "/process/overdue/selectData.htm";
		Map<String,String> map = new HashMap<>();
		map.put("secret",getSecret());
		map.put("processSetCode",setCode);
		map.put("processCode",processCode);
		map.put("processInstanceId",processInstanceId);
		String data = HttpUtils.sendGetForm(url, map);
		MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
		if (message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
			log.error("节点超期信息获取失败，" + message.getDescription());
			return null;
		}
		return JsonUtils.objectToPojo(message.getData(), OverdueHistoryBean.class);
	}

	public static String getSecret() {
		String text = ApplicationConfig.getWorkflowAppCode() + "-" + System.currentTimeMillis();
		return encrypt(text);
	}

	private static String encrypt(String text) {
		try {
			Objects.requireNonNull(text, "要加密的内容不能为空");
			return RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(ApplicationConfig.getWorkflowSecret()), text.getBytes("UTF-8"));
		} catch (Exception e) {
			throw new RuntimeException("加密失败");
		}
	}
}
